﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using COFE.Core.Lister;
using COFE.Core.Profile;
using System.IO;
using COFE.Core.Utils;
using NUnit.Framework;
using COFE.Core.Entry;

namespace COFE.IO.FSI
{
    public class FileSystemDirectoryLister : PrimaryDirectoryListerBase<FileSystemInfo>
    {
        #region Constructors

        public FileSystemDirectoryLister(IFactory<IDirectoryLister> factory, string listerKey, string rootPath = @"C:\")
            : base(factory, listerKey)
        {
            if (String.IsNullOrEmpty(rootPath))
                throw new ArgumentException("Rootpath cannot be null or empty.");
            //if (!Directory.Exists(rootPath))
            //    throw new ArgumentException("Rootpath " + rootPath + " does not exists.");
            
            _rootPath = rootPath.TrimEnd('\\');
            _rootDir = new DirectoryInfo(_rootPath);

            //Directory Lister
            _list = (item) =>
            {
                try { return (item as DirectoryInfo).GetFileSystemInfos(); }
                catch { return new FileSystemInfo[] { }; }
            };
            _isDirectory = (item) => { return item is DirectoryInfo; };
            _getParent = (item) =>
                {
                    Func<FileSystemInfo, bool> isRoot = (itm) =>
                    {
                        return itm.FullName.TrimEnd('\\').Equals(_rootDir.FullName.TrimEnd('\\'));
                    };

                    if (_rootDir != null && isRoot(item))
                    //if (_rootPath != null && item.FullName.Length <= _rootDir.FullName.Length)
                        return null;
                    string parentPath = Path.GetDirectoryName(item.FullName);
                    return String.IsNullOrEmpty(parentPath) ? null : new DirectoryInfo(parentPath);
                };


            //Primar Directory Lister
            _parse = (path) =>
            {
                path = path.TrimEnd('\\');

                if (_rootPath != null)
                    path = _rootPath + "\\" + path;

                if (Directory.Exists(path)) return new DirectoryInfo(path);
                if (File.Exists(path)) return new FileInfo(path);

                return null;
            };

            _getTempPath = () => { return Path.GetTempPath(); };
            _getRootDirectory = () =>
            {
                if (rootPath == null) return (from d in DriveInfo.GetDrives() select d.RootDirectory).ToArray();
                return new FileSystemInfo[] { new DirectoryInfo(rootPath) };
            };
            _getSupportedPathPatterns = () => { return new string[] { RegexPatterns.FileSystemPattern }; };

        }

        #endregion

        #region Methods

        public override IStreamProvider CreateStreamProvider()
        {
            return new FileSystemStreamProvider(this);
        }

        public override IDirectoryController CreateController()
        {
            return new FileSystemDirectoryController(this);
        }

        public override IPropertyProvider CreatePropertyProvider(FileSystemInfo item)
        {
            return new FileSystemPropertyProvider(ListerKey, _rootPath, item);
        }


        #endregion


        #region Data

        private string _rootPath = null;
        private DirectoryInfo _rootDir = null;

        #endregion

        #region Public Properties

        public string RootPath { get { return _rootPath; } }

        #endregion


    }
}
